package com.zhangmeng.tools.utils;


import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;

import lombok.extern.slf4j.Slf4j;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.springframework.web.multipart.MultipartFile;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


@Slf4j
public class PlateUtil {

    public static final int
            CV_FONT_LIGHT = 25,
            CV_FONT_NORMAL = 50,
            CV_FONT_DEMIBOLD = 63,
            CV_FONT_BOLD = 75,
            CV_FONT_BLACK = 87,
            CV_STYLE_NORMAL = 0,
            CV_STYLE_ITALIC = 1,
            CV_STYLE_OBLIQUE = 2,
            CV_LOAD_IMAGE_UNCHANGED = -1,
            CV_LOAD_IMAGE_GRAYSCALE = 0,
            CV_LOAD_IMAGE_COLOR = 1,
            CV_LOAD_IMAGE_ANYDEPTH = 2,
            CV_LOAD_IMAGE_ANYCOLOR = 4,
            CV_IMWRITE_JPEG_QUALITY = 1,
            CV_IMWRITE_PNG_COMPRESSION = 16,
            CV_IMWRITE_PNG_STRATEGY = 17,
            CV_IMWRITE_PNG_BILEVEL = 18,
            CV_IMWRITE_PNG_STRATEGY_DEFAULT = 0,
            CV_IMWRITE_PNG_STRATEGY_FILTERED = 1,
            CV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY = 2,
            CV_IMWRITE_PNG_STRATEGY_RLE = 3,
            CV_IMWRITE_PNG_STRATEGY_FIXED = 4,
            CV_IMWRITE_PXM_BINARY = 32,
            CV_CVTIMG_FLIP = 1,
            CV_CVTIMG_SWAP_RB = 2,
            CV_CAP_MSMF = 1400,
            CV_CAP_ANDROID = 1000,
            CV_CAP_ANDROID_BACK = CV_CAP_ANDROID + 99,
            CV_CAP_ANDROID_FRONT = CV_CAP_ANDROID + 98,
            CV_CAP_XIAPI = 1100,
            CV_CAP_AVFOUNDATION = 1200,
            CV_CAP_GIGANETIX = 1300,
            CV_CAP_PROP_FRAME_WIDTH = 3,
            CV_CAP_PROP_FRAME_HEIGHT = 4,
            CV_CAP_PROP_ZOOM = 27,
            CV_CAP_PROP_FOCUS = 28,
            CV_CAP_PROP_GUID = 29,
            CV_CAP_PROP_ISO_SPEED = 30,
            CV_CAP_PROP_BACKLIGHT = 32,
            CV_CAP_PROP_PAN = 33,
            CV_CAP_PROP_TILT = 34,
            CV_CAP_PROP_ROLL = 35,
            CV_CAP_PROP_IRIS = 36,
            CV_CAP_PROP_SETTINGS = 37,
            CV_CAP_PROP_BUFFERSIZE = 38,
            CV_CAP_PROP_AUTOGRAB = 1024,
            CV_CAP_PROP_PREVIEW_FORMAT = 1026,
            CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE = 301,
            CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL = 302,
            CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL = 303,
            CV_CAP_PROP_PVAPI_BINNINGX = 304,
            CV_CAP_PROP_PVAPI_BINNINGY = 305,
            CV_CAP_PROP_PVAPI_PIXELFORMAT = 306,
            CV_CAP_PROP_XI_DOWNSAMPLING = 400,
            CV_CAP_PROP_XI_DATA_FORMAT = 401,
            CV_CAP_PROP_XI_OFFSET_X = 402,
            CV_CAP_PROP_XI_OFFSET_Y = 403,
            CV_CAP_PROP_XI_TRG_SOURCE = 404,
            CV_CAP_PROP_XI_TRG_SOFTWARE = 405,
            CV_CAP_PROP_XI_GPI_SELECTOR = 406,
            CV_CAP_PROP_XI_GPI_MODE = 407,
            CV_CAP_PROP_XI_GPI_LEVEL = 408,
            CV_CAP_PROP_XI_GPO_SELECTOR = 409,
            CV_CAP_PROP_XI_GPO_MODE = 410,
            CV_CAP_PROP_XI_LED_SELECTOR = 411,
            CV_CAP_PROP_XI_LED_MODE = 412,
            CV_CAP_PROP_XI_MANUAL_WB = 413,
            CV_CAP_PROP_XI_AUTO_WB = 414,
            CV_CAP_PROP_XI_AEAG = 415,
            CV_CAP_PROP_XI_EXP_PRIORITY = 416,
            CV_CAP_PROP_XI_AE_MAX_LIMIT = 417,
            CV_CAP_PROP_XI_AG_MAX_LIMIT = 418,
            CV_CAP_PROP_XI_AEAG_LEVEL = 419,
            CV_CAP_PROP_XI_TIMEOUT = 420,
            CV_CAP_PROP_ANDROID_FLASH_MODE = 8001,
            CV_CAP_PROP_ANDROID_FOCUS_MODE = 8002,
            CV_CAP_PROP_ANDROID_WHITE_BALANCE = 8003,
            CV_CAP_PROP_ANDROID_ANTIBANDING = 8004,
            CV_CAP_PROP_ANDROID_FOCAL_LENGTH = 8005,
            CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR = 8006,
            CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL = 8007,
            CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR = 8008,
            CV_CAP_PROP_ANDROID_EXPOSE_LOCK = 8009,
            CV_CAP_PROP_ANDROID_WHITEBALANCE_LOCK = 8010,
            CV_CAP_PROP_IOS_DEVICE_FOCUS = 9001,
            CV_CAP_PROP_IOS_DEVICE_EXPOSURE = 9002,
            CV_CAP_PROP_IOS_DEVICE_FLASH = 9003,
            CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE = 9004,
            CV_CAP_PROP_IOS_DEVICE_TORCH = 9005,
            CV_CAP_PROP_GIGA_FRAME_OFFSET_X = 10001,
            CV_CAP_PROP_GIGA_FRAME_OFFSET_Y = 10002,
            CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX = 10003,
            CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX = 10004,
            CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH = 10005,
            CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH = 10006,
            CV_CAP_PROP_INTELPERC_PROFILE_COUNT = 11001,
            CV_CAP_PROP_INTELPERC_PROFILE_IDX = 11002,
            CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE = 11003,
            CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE = 11004,
            CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD = 11005,
            CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ = 11006,
            CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT = 11007,
            CV_CAP_ANDROID_COLOR_FRAME_BGR = 0,
            CV_CAP_ANDROID_COLOR_FRAME = CV_CAP_ANDROID_COLOR_FRAME_BGR,
            CV_CAP_ANDROID_GREY_FRAME = 1,
            CV_CAP_ANDROID_COLOR_FRAME_RGB = 2,
            CV_CAP_ANDROID_COLOR_FRAME_BGRA = 3,
            CV_CAP_ANDROID_COLOR_FRAME_RGBA = 4,
            CV_CAP_ANDROID_FLASH_MODE_AUTO = 0,
            CV_CAP_ANDROID_FLASH_MODE_OFF = 0 + 1,
            CV_CAP_ANDROID_FLASH_MODE_ON = 0 + 2,
            CV_CAP_ANDROID_FLASH_MODE_RED_EYE = 0 + 3,
            CV_CAP_ANDROID_FLASH_MODE_TORCH = 0 + 4,
            CV_CAP_ANDROID_FOCUS_MODE_AUTO = 0,
            CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_PICTURE = 0 + 1,
            CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_VIDEO = 0 + 2,
            CV_CAP_ANDROID_FOCUS_MODE_EDOF = 0 + 3,
            CV_CAP_ANDROID_FOCUS_MODE_FIXED = 0 + 4,
            CV_CAP_ANDROID_FOCUS_MODE_INFINITY = 0 + 5,
            CV_CAP_ANDROID_FOCUS_MODE_MACRO = 0 + 6,
            CV_CAP_ANDROID_WHITE_BALANCE_AUTO = 0,
            CV_CAP_ANDROID_WHITE_BALANCE_CLOUDY_DAYLIGHT = 0 + 1,
            CV_CAP_ANDROID_WHITE_BALANCE_DAYLIGHT = 0 + 2,
            CV_CAP_ANDROID_WHITE_BALANCE_FLUORESCENT = 0 + 3,
            CV_CAP_ANDROID_WHITE_BALANCE_INCANDESCENT = 0 + 4,
            CV_CAP_ANDROID_WHITE_BALANCE_SHADE = 0 + 5,
            CV_CAP_ANDROID_WHITE_BALANCE_TWILIGHT = 0 + 6,
            CV_CAP_ANDROID_WHITE_BALANCE_WARM_FLUORESCENT = 0 + 7,
            CV_CAP_ANDROID_ANTIBANDING_50HZ = 0,
            CV_CAP_ANDROID_ANTIBANDING_60HZ = 0 + 1,
            CV_CAP_ANDROID_ANTIBANDING_AUTO = 0 + 2,
            CV_CAP_ANDROID_ANTIBANDING_OFF = 0 + 3,
            IMREAD_UNCHANGED = -1,
            IMREAD_GRAYSCALE = 0,
            IMREAD_COLOR = 1,
            IMREAD_ANYDEPTH = 2,
            IMREAD_ANYCOLOR = 4,
            IMWRITE_JPEG_QUALITY = 1,
            IMWRITE_PNG_COMPRESSION = 16,
            IMWRITE_PNG_STRATEGY = 17,
            IMWRITE_PNG_BILEVEL = 18,
            IMWRITE_PNG_STRATEGY_DEFAULT = 0,
            IMWRITE_PNG_STRATEGY_FILTERED = 1,
            IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY = 2,
            IMWRITE_PNG_STRATEGY_RLE = 3,
            IMWRITE_PNG_STRATEGY_FIXED = 4,
            IMWRITE_PXM_BINARY = 32;

    /**
     * 条形码识别
     */
    public static String zxing_bar_code(String sourcePath) {

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        // 加载为灰度图显示
        Mat source = Imgcodecs.imread(sourcePath,Imgcodecs.IMREAD_GRAYSCALE);
        Mat destination = new Mat(source.rows(), source.cols(), source.type());
        //二值化类型
        Imgproc.threshold(source, destination, 190, 255, Imgproc.THRESH_BINARY);
        String result = parseCode(destination);
        log.info("result:{}",result);
        return result;
    }

    private static String parseCode(Mat mat) {
        String resultText = "无法识别！！！";
        try {
            MultiFormatReader formatReader = new MultiFormatReader();
            BufferedImage image = toBufferedImage(mat);
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);

            Map<DecodeHintType, String> hints = new HashMap<DecodeHintType, String>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");

            Result result = formatReader.decode(binaryBitmap, hints);
            resultText = "解析结果 = " + result.toString() + "\n" +
                    "格式类型 = " + result.getBarcodeFormat() + "\n" +
                    "文本内容 = " + result.getText() + "\n";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultText;
    }

    public static BufferedImage toBufferedImage(Mat m) {
        int type = BufferedImage.TYPE_BYTE_GRAY;
        if (m.channels() > 1) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        int bufferSize = m.channels() * m.cols() * m.rows();
        byte[] b = new byte[bufferSize];
        m.get(0, 0, b); // get all the pixels
        BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        System.arraycopy(b, 0, targetPixels, 0, b.length);
        return image;
    }

    public static String getPdfContent(File file) {
        PdfReader reader = null;
        StringBuilder buff = new StringBuilder();
        try {
            reader = new PdfReader(new FileInputStream(file));
            int num = reader.getNumberOfPages();// 获得页数
            for (int i = 1; i <= num; i++) {
                String textFromPage = PdfTextExtractor.getTextFromPage(reader, i);
                buff.append(textFromPage);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buff.toString();
    }
}
